package com.morgan.storageperlib.utils

import android.app.Activity
import android.app.Application
import android.content.Context
import android.database.Cursor
import android.graphics.Bitmap
import android.net.Uri
import androidx.activity.result.ActivityResult
import java.io.*
import java.nio.ByteBuffer

/**
 *description：
 *<br>author：caowugao
 *<br>time：2021/3/1 0001 18:17
 */

class Utils private constructor() {
    companion object {

        val context : Context by lazy { getApplicationInner()!! }
        private fun getApplicationInner() = run {
            try {
                val activityThread = Class.forName("android.app.ActivityThread")

                val currentApplication = activityThread.getDeclaredMethod("currentApplication")
                val currentActivityThread = activityThread.getDeclaredMethod("currentActivityThread")

                val current = currentActivityThread.invoke(null)
                val app = currentApplication.invoke(current);

                app as? Application
            } catch (e: Throwable) {
                e.printStackTrace()
                null
            }
        }

        fun convertResult2Uri(result : ActivityResult) : Uri? =  if (result.resultCode == Activity.RESULT_OK) result.data?.data else null

        fun makeSureFileExist(file: String) : Boolean{
            val f = File(file)
            if (f.exists()) {
                return true
            }

            return try {
                val parentFile = f.parentFile
                if (parentFile != null && !parentFile.exists()) {
                    parentFile.mkdirs()
                }
                f.createNewFile()
            } catch (e: Throwable) {
                e.printStackTrace()
                false
            }
        }

        fun closeQuietly(close: Closeable?) {
            try {
                close?.close()
            } catch (e: Throwable) {
                e.printStackTrace()
            }
        }
        private fun closeQuietly(cursor: Cursor?) {
            if (null != cursor) {
                try {
                    if (!cursor.isClosed()) {
                        cursor.close()
                    }
                } catch (e: Throwable) {
                    e.printStackTrace()
                }
            }
        }

        fun save(input: InputStream, ouput: OutputStream) : Boolean {
            val buffer = ByteArray(1024)
            var len = 0
            var hasWrite = false
            return try {
                do {
                    //从输入流里读取数据
                    len = input.read(buffer)
                    if (len != -1) {
                        ouput.write(buffer, 0, len)
                        hasWrite = true
                    }
                } while (len != -1)
                if (hasWrite) {
                    ouput.flush()
                }
                hasWrite
            } catch (e: Throwable) {
                e.printStackTrace()
                false
            } finally {
                closeQuietly(input)
                closeQuietly(ouput)
            }
        }

        fun save(path: String, append: Boolean, content: String?): Boolean {
            if (!makeSureFileExist(path)) {
                return false
            }

            var fos: FileOutputStream? = null
            var ow: OutputStreamWriter? = null
            var w: BufferedWriter? = null

            return try {
                fos = FileOutputStream(path, append)
                ow = OutputStreamWriter(fos)
                w = BufferedWriter(ow)
                w.write(if (content == null) "null" else content!!)
                w.flush()
                true
            } catch (e: Throwable) {
                e.printStackTrace()
                false
            } finally {
                closeQuietly(w)
                closeQuietly(ow)
                closeQuietly(fos)
            }
        }

        fun inputStream2String(input: InputStream?) : String {
            var isr : InputStreamReader? = null
            var br : BufferedReader? = null
            return try {
                val result = StringBuilder()
                isr = InputStreamReader(input)
                br = BufferedReader(isr)
                var line : String? = null
                do {
                    line = br.readLine()
                    if (line != null) {
                        result.append(line).append("\n")
                    }
                } while (line != null)
                result.toString()
            } catch (e: Throwable) {
                e.printStackTrace()
                ""
            } finally {
                closeQuietly(br)
                closeQuietly(isr)
                closeQuietly(input)
            }
        }

        fun bitmap2ByteArray(bitmap: Bitmap) : ByteArray? {
            return try {
                val bytes: Int = bitmap.byteCount
                val buf: ByteBuffer = ByteBuffer.allocate(bytes)
                bitmap.copyPixelsToBuffer(buf)
                buf.array()
            } catch (e: Throwable) {
                e.printStackTrace()
                null
            }
        }

        fun byteArray2Bitmap(byteArray: ByteArray, width : Int, height : Int, config : Bitmap.Config) : Bitmap?{
            return try {
                val bitmap = Bitmap.createBitmap(width, height, config)
                bitmap.copyPixelsFromBuffer(ByteBuffer.wrap(byteArray))
                bitmap
            } catch (e : Throwable) {
                e.printStackTrace()
                null
            }
        }
    }

}